package com.angysnail.guava.monitor;

import java.util.concurrent.TimeUnit;

import com.google.common.util.concurrent.Monitor;

public class MonitorTest2<V> {
	private final Monitor monitor = new Monitor();
	private final Monitor.Guard valuePresent = new Monitor.Guard(monitor) {
		public boolean isSatisfied() {
			return value != null;
		}
	};
	private final Monitor.Guard valueAbsent = new Monitor.Guard(monitor) {
		public boolean isSatisfied() {
			return value == null;
		}
	};
	private V value;

	public V get() throws InterruptedException {
		monitor.enterWhen(valuePresent);
		try {
			V result = value;
			value = null;
			return result;
		} finally {
			monitor.leave();
		}
	}

	public void set(V newValue) throws InterruptedException {
		monitor.enterWhen(valueAbsent);
		try {
			value = newValue;
		} finally {
			monitor.leave();
		}
	}

	public static void main(String[] args) throws InterruptedException {
		MonitorTest2<String> mt = new MonitorTest2<String>();
		new Thread() {
			public void run() {
				try {
					String value = mt.get();
					System.out.println(String.format("%s, %s", Thread.currentThread(), value));
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			};
		}.start();
		TimeUnit.SECONDS.sleep(5);
		new Thread() {
			public void run() {
				try {
					mt.set("value setted");
					System.out.println(String.format("%s, %s", Thread.currentThread(), " set the value already!"));
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			};
		}.start();
	}
}
